﻿@using CID.Web.Support
@using CID.Web.Support.TemplateContentEdition
@using CID.Web.Models.Infrastructure

@model TemplateViewModel

<div id="Tabs">
    <ul>
        <li><a href="#General">General</a></li>
        <li><a href="#Parameters">Parameters</a></li>
    </ul>
    <div id="General">
        @using (Html.BeginForm())
        {
            @Html.ValidationSummary(true)
            <div class="editor-label">
                @Html.LabelFor(model => model.TemplateType)
            </div>
            <div class="editor-field">
                @if (!Model.TemplateTypeId.HasValue)
                {
                    @Html.KODropDownListForEntity(m => m.TemplateTypeId, Model.AvailableTemplateTypes, Model.TemplateTypeId)
                    @Html.ValidationMessageFor(model => model.TemplateTypeId)
                }
                else
                {
                    @Html.DisplayFor(m => m.TemplateType)
                }
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Purpose)
            </div>
            <div class="editor-field">
                @if (!Model.TemplateTypeId.HasValue)
                {
                    @Html.KODropDownListForEnum(model => model.Purpose, typeof(CID.Web.Models.Infrastructure.TemplatePurpose))
                    @Html.ValidationMessageFor(model => model.Purpose)
                }
                else
                {
                    @Html.DisplayFor(m => m.Purpose)
                }
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Name)
            </div>
            <div class="editor-field">
                @Html.KOTextBoxFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Description)
            </div>
            <div class="editor-field">
                @Html.KOTextAreaFor(model => model.Description)
                @Html.ValidationMessageFor(model => model.Description)
            </div>
            <div>
            @if (Model.TemplateTypeId.HasValue)
            {
            <div class="editor-label">
                @Html.LabelFor(model => model.Content)
            </div>
            <div class="editor-field">
                @Html.TemplateContentEditor()
                @Html.ValidationMessageFor(model => model.Content)
            </div>
            }
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.MultipleServersSupport)
            </div>
            <div class="editor-field">
                @Html.KOCheckBoxFor(model => model.MultipleServersSupport)
                @Html.ValidationMessageFor(model => model.MultipleServersSupport)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Enabled)
            </div>
            <div class="editor-field">
                @Html.KOCheckBoxFor(model => model.Enabled)
                @Html.ValidationMessageFor(model => model.Enabled)
            </div>
            @Html.KOHiddenFor(model => model.Id)
        }
    </div>
    <div id="Parameters">
        <div data-bind="template: {name: 'ParameterEditorTemplate', data: EditingParameter, afterRender: OnParameterEditorTemplateRender}"></div>
        <table>
            <thead>
                <tr>
                    <th>
                        Type
                    </th>
                    <th>
                        Name
                    </th>
                    <th>
                        Description
                    </th>
                    <th>
                    </th>
                </tr>
            </thead>
            <tbody data-bind="template: {name: 'ParameterDisplayTemplate', foreach: Parameters}">
            </tbody>
        </table>
        <p><input type="button" value="Add New" data-bind="click: NewParameter" /></p>
    </div>
    <p> <input type="Button" value="Save" data-bind="click: Save" /> </p>

</div>
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script id="ParameterDisplayTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>${Type}</td>
        <td>${Name}</td>
        <td>${Description}</td>
        <td> <input type="button" value="Edit" data-bind="click: Edit" /> | <input type="button" value="Delete" data-bind="click: Delete" /></td>
    </tr>
</script>

<script id="ParameterEditorTemplate" type="text/x-jquery-tmpl">
    @Html.KOPartialChildEditor("ParameterEditor", "Parameter", new ParameterViewModel())
</script>

<script type="text/javascript">
    $(document).ready(function () {
        $("#Tabs").tabs();
        viewModel.Load();
        ko.applyBindings(viewModel);
    });

    function Trim(value) {
        return value.replace(/^\s+/g, '').replace(/\s+$/g, '')
    }

    function MapParameter(options) {
        var p = options.data;
        return new Parameter(p.Id, p.Type, p.Name, p.Description);
    }

    var Parameter = function (id, type, name, description) {
        this.Id = ko.observable(id);
        this.Type = ko.observable(type);
        this.Name = ko.observable(name);
        this.Description = ko.observable(description);
        this.Selected = ko.observable(false);
        this.Editing = ko.observable(false);
        this.IsValid = ko.dependentObservable(function () {
            return ((Trim(this.Type()).length > 0) && (Trim(this.Name()).length > 0) && (Trim(this.Description()).length > 0))
        }, this);
        this.Select = function () {
            if (viewModel.SelectedParameter()) viewModel.SelectedParameter().Unselect();
            this.Selected(true);
            viewModel.SelectedParameter(this);
        };
        this.Unselect = function () {
            if (this.Selected()) {
                this.Selected(false);
                viewModel.SelectedParameter(null);
            }
        };
        this.Edit = function () {
            this.Select();
            this.Editing(true);
            viewModel.BeginEdit(this);
        };
        this.Delete = function () {
            viewModel.RemoveParameter(this);
        };
        this.UpdateWith = function (parameter) {
            this.Type(parameter.Type());
            this.Name(parameter.Name());
            this.Description(parameter.Description());
        };
        this.Apply = function () {
            viewModel.SelectedParameter().UpdateWith(this());
            viewModel.EndEdit(null);
        };
        this.Cancel = function () {
            viewModel.EndEdit();
        };
    };

    var viewModel = {
        Id: ko.observable(),
        TemplateTypeId: ko.observable(),
        Name: ko.observable(),
        Content: ko.observable(),
        Description: ko.observable(),
        Purpose: ko.observable(),
        MultipleServersSupport: ko.observable(),
        Enabled: ko.observable(),
        Parameters: ko.observableArray([]),
        SelectedParameter: ko.observable(),
        EditingParameter: ko.observable(),
        BeginEdit: function (parameter) {
            var param = new Parameter(0, "", "", "");
            param.UpdateWith(parameter);
            this.EditingParameter(param);
        },
        EndEdit: function () {
            this.SelectedParameter().Editing(false);
            this.EditingParameter(null);
        },
        AddParameter: function (parameter) {
            this.Parameters.push(parameter);
        },
        NewParameter: function () {
            var parameter = new Parameter(0, "", "New Parameter", "");
            this.AddParameter(parameter);
            parameter.Edit();
            return parameter;
        },
        RemoveParameter: function (parameter) {
            if (parameter.Editing()) this.EditingParameter().Cancel();
            if (parameter.Selected()) parameter.Unselect();

            this.Parameters.destroy(parameter);
        },
        OnParameterEditorTemplateRender: function (elements) {
            //when the editor template is rendered, the form it contains needs to be reparsed to attach it to the unobstrusive validation
            var formSelector = elements.first().parent().find('form');
            if (formSelector.is('form')) {
                $.validator.unobtrusive.parseDynamicContent(formSelector);
                formSelector.validate();
                formSelector.valid();
            }
        },
        Load: function () {
            var mapping = {
                'Parameters': {
                    create: function (options) { return MapParameter(options); }
                }
            }
            ko.mapping.fromJS(@Html.JSON(Model), mapping, this);
        },
        Save: function () {
            var viewModelJSON = ko.toJSON(ko.mapping.toJS(this));
            $.ajax({
                url: this.PostUrl(),
                data: viewModelJSON,
                type: 'POST',
                contentType: 'application/json;',
                dataType: 'json',
                success: function (response) {
                    switch (response.Type) {
                        case "Redirect":
                            window.location.href = response.Url;
                            break;
                        case "View":
                            //TODO: display error in the summary error pane. Need to research how that's done with unobtrusive validation
                            alert(response.ModelError);
                            break;
                    }
                }
            });

        }
    };
</script>
